from Miranda import RuleSubject, RuleVerb, RuleSetting
from datetime import date, datetime, timedelta

import Miranda
import kronos
import os.path
import time
import unittest

#! /usr/bin/python

__author__ = "zainul"
__date__ = "$24/06/2010 5:45:19 PM$"


class MirandaTest(unittest.TestCase):
    
    def setUp(self):
        
        Miranda.CONFIG_FILE_DIR = '../test/resource/' 
        Miranda.init_logging()
        files = os.listdir( './resource/folder/' );
        
        for eachFile in files:
            filePath = './resource/folder/' + eachFile
            if os.path.isdir(filePath):
                continue;        
            os.remove(filePath);
                        
        testFile = open('./resource/test3.txt','w');
        testFile.write("test");
        
        testFile = open('./resource/test4.txt','w');
        testFile.write("test");
        
        testFile = open('./resource/test5.txt','w');
        testFile.write("test");
        
        testFile = open('./resource/folder/test5.txt','w');
        testFile.write("test");
        
        testFile = open('./resource/test6.txt','w');
        testFile.write("test");
        
        testFile = open('./resource/testfile.txt','w');
        testFile.write("test");
        
        test_config_file = open('./resource/config.yaml','w');
        test_config_file.write("");


    def test_doFileOperation_any(self):
        
        rule_verb = Miranda.RuleVerb();
        rule_verb.dest_folder = './resource/folder';
        rule_verb.type = Miranda.RuleVerb.COPY;
        
        rule_subject = Miranda.RuleSubject();
        rule_subject.criteria = Miranda.IS
        rule_subject.value = 'my file';
        rule_subject.file_component_type = Miranda.FILE_NAME;
        
        ruleSetting = Miranda.RuleSetting();
        ruleSetting.source_folder = "./resource/source";
        ruleSetting.enabled = True
        
        rule= Miranda.Rule();
        rule.rule_setting = ruleSetting;
        rule.rule_condition = "ANY";
        rule.rule_subjects.append(rule_subject)
        rule.rule_verb = rule_verb;
        
        Miranda.do_file_operation(rule);
        
        self.assertTrue(os.path.isfile('./resource/folder/my file.txt'))
        self.assertFalse(os.path.isfile('./resource/folder/my file 2.txt'))
        self.assertFalse(os.path.isfile('./resource/folder/test.txt'))
        self.assertFalse(os.path.isfile('./resource/folder/another file.txt'))
        
    def test_doFileOperation_all(self):
        
        rule_verb = Miranda.RuleVerb();
        rule_verb.dest_folder = './resource/folder';
        rule_verb.type = Miranda.RuleVerb.COPY;
        
        rule_subject = Miranda.RuleSubject();
        rule_subject.criteria = Miranda.IS
        rule_subject.value = 'txt';
        rule_subject.file_component_type = Miranda.FILE_EXT;
        
        rule_subject2 = Miranda.RuleSubject();
        rule_subject2.criteria = Miranda.CONTAINS
        rule_subject2.value = 'file';
        rule_subject2.file_component_type = Miranda.FILE_NAME
        
        rule_setting = Miranda.RuleSetting();
        rule_setting.source_folder = "./resource/source";
        rule_setting.enabled = True
        
        rule = Miranda.Rule();
        rule.rule_condition = "ALL"
        rule.rule_setting = rule_setting
        rule.rule_subjects.append(rule_subject)
        rule.rule_subjects.append(rule_subject2)
        rule.rule_verb = rule_verb
        
        Miranda.do_file_operation(rule);
        
        self.assertTrue(os.path.isfile('./resource/folder/my file.txt'))
        self.assertTrue(os.path.isfile('./resource/folder/my file 2.txt'))
        self.assertTrue(os.path.isfile('./resource/folder/another file.txt'))

    def test_recursionFileOperation_all(self):
        
        rule_verb = Miranda.RuleVerb();
        rule_verb.dest_folder = './resource/folder';
        rule_verb.type = Miranda.RuleVerb.COPY;
        
        rule_subject = Miranda.RuleSubject();
        rule_subject.criteria = Miranda.IS
        rule_subject.value = 'txt';
        rule_subject.file_component_type = Miranda.FILE_EXT;
        
        rule_subject2 = Miranda.RuleSubject();
        rule_subject2.criteria = Miranda.CONTAINS
        rule_subject2.value = 'test';
        rule_subject2.file_component_type = Miranda.FILE_NAME
        
        rule_setting = Miranda.RuleSetting();
        rule_setting.source_folder = "./resource/recursive";
        rule_setting.recursive = True;
        rule_setting.enabled = True;
        
        rule = Miranda.Rule()
        rule.rule_condition = "ALL"
        rule.rule_verb = rule_verb
        rule.rule_subjects.append(rule_subject)
        rule.rule_subjects.append(rule_subject2)
        rule.rule_setting = rule_setting
        
        Miranda.do_file_operation(rule);
        
        self.assertTrue(os.path.isfile('./resource/folder/test_2.txt'))
        self.assertTrue(os.path.isfile('./resource/folder/test_1.txt'))
        
        
    def test_getFileComponent(self):
        file_name = Miranda.get_file_component("./resource/test.txt",Miranda.FILE_NAME);
        self.assertEqual("test",file_name);

        file_ext = Miranda.get_file_component("./resource/test.txt",Miranda.FILE_EXT);
        self.assertEqual("txt",file_ext);

    def test_match(self):
                
        self.assertTrue(Miranda.match("test",Miranda.IS,"test"));
        self.assertFalse(Miranda.match("test",Miranda.IS_NOT,"test"));
        self.assertTrue(Miranda.match("myfile",Miranda.CONTAINS,"file"));
        self.assertTrue(Miranda.match("abc",Miranda.DOES_NOT_CONTAIN,"xyz"));
        self.assertTrue(Miranda.match(0,Miranda.EQUAL,0));
        self.assertTrue(Miranda.match(0,Miranda.NOT_EQUAL,1));
        self.assertTrue(Miranda.match(2,Miranda.GREATER_THAN,1));
        self.assertTrue(Miranda.match(9,Miranda.LESS_THAN,10));
        
        last_5_minute_timestamp = time.mktime((datetime.now() + timedelta (minutes=- 5)).timetuple())
        last_2_hr_timestamp = time.mktime((datetime.now() + timedelta (hours=- 2)).timetuple())
        
        self.assertTrue(Miranda.match(last_5_minute_timestamp,Miranda.IS_IN_THE_LAST,1,Miranda.RuleSubject.HOUR));
        self.assertTrue(Miranda.match(last_2_hr_timestamp,Miranda.IS_NOT_IN_THE_LAST,1,Miranda.RuleSubject.HOUR));
                
        self.assertTrue(Miranda.match("my test file",Miranda.MATCHES_ONE_OF,'file1,my test file,file2'));
        self.assertFalse(Miranda.match("any file",Miranda.MATCHES_ONE_OF,'file1,my test file,file2'));
        self.assertTrue(Miranda.match("test file",Miranda.DOES_NOT_MATCH_ONE_OF,'file1,my test file,file2'));

    def test_fileNameList(self):
        rule = RuleSubject();
        rule.file_name_list="the big bang theory,fringe,the middle"
        file_names = rule.get_value();
        self.assertEquals('the big bang theory',file_names[0]);
        self.assertEquals('fringe',file_names[1]);
        self.assertEquals('the middle',file_names[2]);
        
    def test_getValue(self):
        rule = RuleSubject();
        rule.value = 2;
        rule.uom = RuleSubject.MINUTE;

        self.assertEqual(120,rule.get_value());

        rule.value = 2;
        rule.uom = RuleSubject.HOUR;

        self.assertEqual(2 * 60 * 60,rule.get_value());

        rule.value = 1;
        rule.uom = RuleSubject.DAY;

        self.assertEqual(1 * 24 * 3600,rule.get_value());

        rule.value = 1;
        rule.uom = RuleSubject.WEEK;
        self.assertEqual(1 * 7 * 24 * 3600,rule.get_value());

        rule.value = 1;
        rule.uom = RuleSubject.MONTH;

        self.assertEqual(1 * 30 * 24 * 3600,rule.get_value());

        rule.value = 1;
        rule.uom = RuleSubject.YEAR;

        self.assertEqual(1 * 365 * 24 * 3600,rule.get_value());

        rule.value = 1;
        rule.uom = RuleSubject.KB;

        self.assertEqual(1024,rule.get_value());

        rule.value = 1;
        rule.uom = RuleSubject.MB;

        self.assertEqual(1048576,rule.get_value());
    
   
        
    def test_ActionFile(self):
        operation = Miranda.RuleVerb()
        operation.type = Miranda.RuleVerb.COPY
        operation.dest_folder = "./resource/folder/test2.txt"
        
        Miranda.action_file(operation, "./resource/test2.txt");
        
        operation.type = Miranda.RuleVerb.MOVE
        operation.dest_folder = "./resource/folder/";
        Miranda.action_file(operation, "./resource/test3.txt");
        
        
        self.assertTrue(os.path.isfile("./resource/folder/test3.txt"));
        self.assertFalse(os.path.isfile("./resource/test3.txt"));
        
        operation.type = Miranda.RuleVerb.DELETE
        Miranda.action_file(operation, "./resource/test4.txt");
        self.assertFalse(os.path.isfile("./resource/test4.txt"));
        
        operation.type = Miranda.RuleVerb.RENAME
        operation.new_file_name = 'renamed_testfile';
        Miranda.action_file(operation, "./resource/testfile.txt");
        self.assertTrue(os.path.isfile('./resource/renamed_testfile.txt'));
               
        operation.type = Miranda.RuleVerb.MOVE
        operation.overwrite = False
        operation.dest_folder = "./resource/folder/"
        self.assertEquals(-1,Miranda.action_file(operation,  "./resource/test5.txt"))
        
        operation.type = Miranda.RuleVerb.MOVE
        operation.overwrite = True
        operation.dest_folder = "./resource/folder/"
        self.assertEquals(1,Miranda.action_file(operation,  "./resource/test5.txt"))
        
        operation.type = Miranda.RuleVerb.MOVE
        operation.overwrite = True
        operation.compression = True
        operation.dest_folder = "./resource/folder/"
        self.assertEquals(1,Miranda.action_file(operation,  "./resource/test6.txt"))
        self.assertTrue(os.path.isfile("./resource/folder/test6.zip"));
     
    def test_run(self):
        
        rule_verb = Miranda.RuleVerb();
        rule_verb.dest_folder = './resource/folder';
        rule_verb.type = Miranda.RuleVerb.COPY;
        
        rule_subject = Miranda.RuleSubject();
        rule_subject.criteria = Miranda.IS
        rule_subject.value = 'my file';
        rule_subject.file_component_type = Miranda.FILE_NAME;
        
        ruleSetting = Miranda.RuleSetting();
        ruleSetting.source_folder = "./resource/source";
        ruleSetting.enabled = True;
        
        rule= Miranda.Rule();
        rule.rule_setting = ruleSetting;
        rule.rule_condition = "ANY";
        rule.rule_subjects.append(rule_subject)
        rule.rule_verb = rule_verb;
        
        
        rule_dict = {}
        rules = [rule]
        rule_dict[ "./resource/source"] = rules
        config = Miranda.Config();
        config.rule_dict = rule_dict;
        
        scheduler = Miranda.Scheduler();
        scheduler.config = config;
        scheduler.__execute_rules__();
        
        self.assertTrue(os.path.isfile('./resource/folder/my file.txt'))
        
    def test_equal_rule(self):
        
        rule1_setting = Miranda.RuleSetting();
        rule1_setting.source_folder = 'Programming Folder';
        rule1_setting.description = 'filter';
        
        rule1 = Miranda.Rule();
        rule1.rule_setting = rule1_setting;
        
        self.assertTrue(rule1 == rule1)
        
        rule2_setting = Miranda.RuleSetting();
        rule2_setting.source_folder = 'Programming Folder';
        rule2_setting.description = 'filter';
        
        rule2 = Miranda.Rule();
        rule2.rule_setting = rule2_setting;
        
        self.assertTrue(rule1 == rule2)
        
        rule3_setting = Miranda.RuleSetting();
        rule3_setting.source_folder = 'Other Folder';
        rule3_setting.description = 'filter';
        
        rule3 = Miranda.Rule();
        rule3.rule_setting = rule3_setting;
        
        self.assertTrue(rule1 != rule3)
        
        rules = [rule1]
        self.assertEquals(0,rules.index(rule2));
        self.assertEquals(0,rules.index(rule1));
        
        exceptionRaised = False;
        try:
            rules.index(rule3);            
        except ValueError:
            exceptionRaised = True;
            
        self.assertTrue(exceptionRaised)
    
    def test_validation(self):
        
        ruleSetting = RuleSetting();
        ruleSetting.source_folder = './source'
        ruleSetting.description = 'rule 1'
                       
        rule = Miranda.Rule();        
        rule.rule_setting = ruleSetting        

        config = Miranda.Config();
        config.rule_dict['./source'] = [rule]
                        
        Miranda.dump_rules(config,'../test/resource/config.yaml')
        
        new_rule_setting = RuleSetting();
        new_rule_setting.source_folder = './source'
        new_rule_setting.description = 'rule 1'
                       
        new_rule = Miranda.Rule();        
        new_rule.rule_setting = new_rule_setting
        new_rule.isNew = True;
        
        validation_result = Miranda.validate_rule(new_rule,'../test/resource/config.yaml')
        
        self.assertEquals(Miranda.VALIDATION_SAME_RULE,validation_result)
        
        
        new_rule_setting = RuleSetting();
        new_rule_setting.source_folder = './source'
        new_rule_setting.description = 'rule 1'
                       
        new_rule = Miranda.Rule();        
        new_rule.rule_setting = new_rule_setting
        new_rule.isNew = False
        
        validation_result = Miranda.validate_rule(new_rule,'../test/resource/config.yaml')
        
        self.assertEquals(None,validation_result)
        
        new_rule_setting = RuleSetting();
        new_rule_setting.source_folder = './source'
        new_rule_setting.description = ''
                       
        new_rule = Miranda.Rule();        
        new_rule.rule_setting = new_rule_setting
        new_rule.isNew = False
        
        validation_result = Miranda.validate_rule(new_rule,'../test/resource/config.yaml')
        
        self.assertEquals(Miranda.VALIDATION_NO_DESC,validation_result)
        
    
    def test_bin_mgr(self):
                
        Miranda.CONFIG_FILE_DIR = '../test/resource/'
        bin_manager = Miranda.BinManager();
        bin_manager.is_empty_recycle_bin_enabled = True
        bin_manager.interval = 5
        bin_manager.uom = Miranda.MINUTES
        
        five_min_ago = datetime.now() + timedelta (minutes=- 5)        
        bin_manager.first_enabled_time = five_min_ago;
        
        config = Miranda.Config()
        config.bin_manager = bin_manager;    
        
        scheduler = Miranda.Scheduler(); 
        scheduler.config = config;       
        scheduler.__execute_bin_mgr__();
               
        self.assertTrue(scheduler.config.bin_manager.first_enabled_time > five_min_ago) 
        
        bin_manager = Miranda.BinManager();
        bin_manager.is_empty_recycle_bin_enabled = True
        bin_manager.interval = 20
        bin_manager.uom = Miranda.MINUTES
        
        ten_min_ago = datetime.now() + timedelta (minutes=- 10)        
        bin_manager.first_enabled_time = ten_min_ago;
        
        config = Miranda.Config()
        config.bin_manager = bin_manager;
        
        Miranda.dump_rules(config,'../test/resource/config.yaml' )
        
        scheduler = Miranda.Scheduler();
        scheduler.config = config;
        scheduler.__execute_bin_mgr__();
        
        config = Miranda.read_config('../test/resource/config.yaml');
        self.assertEquals(ten_min_ago,scheduler.config.bin_manager.first_enabled_time)  
        
    def test_dump_rule(self):
        
        ruleSetting = RuleSetting();
        ruleSetting.source_folder = './source'
        ruleSetting.description = 'rule 1'
                       
        rule = Miranda.Rule();        
        rule.rule_setting = ruleSetting        

        config = Miranda.Config();
        config.rule_dict['./source'] = [rule];
                       
        Miranda.dump_rules(config,'../test/resource/config.yaml')
        
        rule_dict = Miranda.read_config('../test/resource/config.yaml').rule_dict
        self.assertTrue(rule_dict.has_key('./source'))
        self.assertEquals(1,len(rule_dict.get('./source')))
        
        rule_setting_2 = RuleSetting();
        rule_setting_2.source_folder = './source'
        rule_setting_2.description = 'rule 2'
        
        rule = Miranda.Rule();        
        rule.rule_setting = rule_setting_2 
        
        config = Miranda.Config();
        config.rule_dict['./source'] = [rule];
                       
        Miranda.dump_rules(config,'../test/resource/config.yaml')
                
        rule_dict = Miranda.read_config('../test/resource/config.yaml').rule_dict
        self.assertTrue(rule_dict.has_key('./source'))
        self.assertEquals(1,len(rule_dict.get('./source')))
        
        rule_setting_3 = RuleSetting();
        rule_setting_3.source_folder = './other'
        rule_setting_3.description = 'rule 3'
        
        rule3 = Miranda.Rule();        
        rule3.rule_setting = rule_setting_3 
        
        config = Miranda.Config();
        config.rule_dict['./other'] = [rule3];
        config.rule_dict['./source'] = [rule];
                       
        Miranda.dump_rules(config,'../test/resource/config.yaml')
                
        rule_dict = Miranda.read_config('../test/resource/config.yaml').rule_dict
        self.assertTrue(rule_dict.has_key('./source'))
        self.assertTrue(rule_dict.has_key('./other'))
        self.assertEquals(1,len(rule_dict.get('./other')))            
               

class TestObserver:
    
    def __init__(self):
        self.notified = False
    
    def update_main_screen(self,rule):
        self.notified = True
     
                
if __name__ == "__main__":
   unittest.main()


